home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / xnot12a.zip / MOUSE.C < prev    next >
C/C++ Source or Header  |  1993-05-20  |  12KB  |  508 lines

  1. #include "jam.h"
  2. #ifdef WINDOWED /* whole file */
  3.  
  4. /*
  5. * Mouse support routines. Some code taken from original Amigamouse
  6. * code in Mg2a and enhanced/modified almost beyond recognition. This 
  7. * code supports 
  8. *
  9. *    set mark
  10. *    set dot
  11. *    select region and copy/kill it
  12. *    resize window(s)
  13. *    scroll window(s)
  14. *
  15. * via string commands stuffed into the input stream from the 
  16. * window level code. It ain't pretty, but it gets the job done.
  17. *
  18. */  
  19. #include "def.h"
  20. #include "stdio.h"
  21. #include "keyname.h"
  22. #include "macro.h" 
  23. #include "kbd.h"
  24.  
  25. /* string-to-verb matching for mousecmd subcommands
  26.  */
  27. #define LEFTDOWN    0
  28. #define RIGHTDOWN    1
  29. #define LEFTUP        2
  30. #define MOVE        3
  31. #define DBLCLICK    4
  32. #define LEFTDOWNSHIFT    5
  33. #define M_ABORT        6
  34. #define M_TIMER        7
  35.  
  36. static BOOL rn_(setmousepos,(int row, int col, BOOL left));
  37. static void rn_(movedot,(int row, int col));
  38. static int rn_(subcommand,(char *s));
  39.  
  40. static int downrow = -1, downcol = -1;  /* initial down during move.. */
  41. static int oldrow = -1, oldcol = -1;    /* last mouse click    */
  42. static int newrow, newcol;        /* next mouse click    */
  43. static BOOL inmodeline = FALSE;
  44. static BOOL bottommodeline = FALSE;
  45. static BOOL mouseDown = FALSE;
  46. static BOOL mouseMoving = FALSE;
  47. static EWINDOW *touchedWp;
  48. static BOOL mshift = FALSE;
  49. static BOOL didsetmark = FALSE;
  50. static EWINDOW *mwp, *mwp1;        /* window(s) mouse is in */
  51. static int mdoto, mdoto1, mcol1;    /* line offset of mouse */
  52. static LINE *mdotp, *mdotp1;        /* the real line the mouse is on */
  53.  
  54. static char *cancel = "Cancelled!";
  55. static char *diffw = "Different window.";
  56. static char *shiftm = "Shift key will reverse scroll direction.";
  57. static char *movecopy = "Mark set; move cursor (dot) to define region to %s.";
  58. static char *mv = "move";
  59. static char *cp = "copy";
  60.  
  61. /* relative-command - return if last click was in modeline
  62.  */
  63. BOOL minmodeline()
  64. {
  65.   return (inmodeline);
  66. }
  67. /*
  68.  * Utility routine to move dot to where the user clicked. 
  69.  * Optional 'move' flag to make move permanent vs just
  70.  * locating new dot.
  71.  */
  72. int dottomouse(inrow, incol, move)
  73. int inrow;
  74. int incol;
  75. BOOL move;
  76. {
  77.   register EWINDOW *wp;
  78.   register int    dot;
  79.   register int    col;
  80.   register int    c, nlines;
  81.   
  82.   inmodeline = FALSE;   /* always reset */
  83.   bottommodeline = FALSE;
  84.   newrow = inrow;
  85.   newcol = incol;
  86.   
  87.   if (macrodef) 
  88.     {
  89.       ewprintf(notinmacro);
  90.       return (FALSE);
  91.     }
  92.   
  93.   /* Find out which window was clicked in                
  94.    */
  95.   for (wp = wheadp; wp != NULL; wp = wp->w_wndp)
  96.     if (newrow == (wp->w_toprow + wp->w_ntrows))
  97.       {
  98.     touchedWp = wp;
  99.     inmodeline = TRUE;
  100.     if (!wp->w_wndp)         /* no next window? */
  101.       bottommodeline = TRUE;
  102.       }
  103.     else if ((newrow >= wp->w_toprow) && 
  104.          (newrow <= (wp->w_toprow + wp->w_ntrows)))
  105.       break;
  106.   
  107.   /* Impossible?
  108.    */
  109.   if (wp == NULL)
  110.     return (ABORT);
  111.  
  112.   else /* Compute the new location; optionally move there */
  113.     {
  114.       EWINDOW *savewp = curwp;
  115.       BUFFER *savebp = curbp;
  116.       LINE *savedotp = curwp->w_dotp;
  117.       int savedoto = curwp->w_doto;
  118.       
  119.       /* Move to selected window, move dot to top left    
  120.        * then advance as possible to mouse point.
  121.        */
  122.       curwp = wp;
  123.       curbp = wp->w_bufp;
  124.       curwp->w_dotp = wp->w_linep;
  125.       curwp->w_doto = 0;
  126.       
  127.       /* Go forward the correct # of lines
  128.        */
  129.       nlines = newrow - curwp->w_toprow;
  130.       for (; nlines > 0; nlines--)
  131.     {
  132.       /* Wrap around?  Don't insert blank lines in file
  133.        */
  134.       if (lforw(curwp->w_dotp) == curbp->b_linep)
  135.         break;
  136.       forwline(FFRAND, 1);
  137.         }
  138.       
  139.       /* Go forward the correct # of characters    
  140.        * need to count them out because of tabs    
  141.        */
  142.       col = dot = 0;
  143.       while ((col < newcol) && (dot < llength(curwp->w_dotp))) 
  144.     {
  145.       c = lgetc(curwp->w_dotp, dot++);
  146.       if (c == CCHR('I'))
  147.         col |= TABROUND;
  148.       else if (ISCTRL(c) != FALSE)
  149.         ++col;
  150.       ++col;
  151.     }
  152.       if (col > newcol) 
  153.     dot--;    /* back up to tab/ctrl char */
  154.       forwchar(FFRAND, dot);
  155.       
  156.       /* not supposed to move? reset but remember where it
  157.        * would have been
  158.        */
  159.       mwp = curwp;
  160.       mdoto = curwp->w_doto;
  161.       mdotp = curwp->w_dotp;        
  162.       
  163.       if (!move)
  164.     {
  165.       curwp = savewp;
  166.       curbp = savebp;
  167.       curwp->w_dotp = savedotp;
  168.       curwp->w_doto = savedoto;
  169.     }
  170.     }
  171.   
  172.   return (TRUE);
  173. }
  174. /* Handle mouse generated things
  175.  */
  176. int mousecmd(f, n)
  177. int f, n;
  178. {
  179.   char buf[256];
  180.   int subcmd;
  181.   static int row, col;
  182.   BOOL killit = FALSE; 
  183.   static BOOL drawn = FALSE;
  184. #define IsAbort ((subcmd == M_ABORT) || killit)
  185. #define SetAbort() killit = TRUE
  186.  
  187.   /* Read the subcommand which is waiting in input stream.
  188.    */
  189.   getcmdinput(buf);
  190.   if (buf[0])
  191.     {
  192.       subcmd = subcommand(buf);  /* Convert subcommand to verb */
  193.       switch(subcmd)
  194.     {
  195.     case M_ABORT:
  196.           ewprintf(cancel);
  197.           ttbeep();
  198.           /* FALLTHRU */
  199.     case LEFTUP:
  200.       {
  201.         BOOL copy = FALSE; 
  202.         BOOL kill = FALSE; 
  203.         EWINDOW *savewp = curwp;
  204.         BUFFER *savebp = curbp;
  205.         LINE *savedotp = curwp->w_dotp;
  206.         int savedoto = curwp->w_doto;
  207.         
  208.         /* make window cursor normal, then find
  209.          * position UP occurred
  210.          */
  211.         WindowNormalCursor();
  212.         if (drawn)                /* erase old */
  213.               {
  214.             movedot(row, col);
  215.                 drawn = FALSE;
  216.               }
  217.         if (!IsAbort)            /* abort has no params */
  218.               {
  219.                 getcmdinput(buf);
  220.             sscanf(buf, posFormat, &row, &col);
  221.           }
  222.  
  223.             if (!mouseDown)    /* up after abort? */
  224.               return (TRUE);    /* no other bell */
  225.  
  226.             if (inmacro)
  227.               {
  228.                 ewprintf(notinmacro);
  229.                 return FALSE;    /* can't record mouse actions */
  230.               }
  231.  
  232.             if (didsetmark)  /* didn't do this for modeline move */
  233.               {
  234.             if (IsCaretCreated())
  235.               SetCaretVis(FALSE);      /* make sure no display weirdness */  
  236.  
  237.             if (mwp1 != mwp)
  238.                   {
  239.                     ewprintf(diffw);       /* operation can't span windows */
  240.                     SetAbort();
  241.                   }
  242.             curwp = savewp;
  243.             curbp = savebp;
  244.             curwp->w_dotp = savedotp;
  245.             curwp->w_doto = savedoto;
  246.         
  247.             /* Set dot at up point. If real motion occurred,
  248.              * set appropriate verb (copy/kill).
  249.              */
  250.                 if (!IsAbort)
  251.                   {
  252.                 dottomouse(row, col, TRUE);
  253.                 if ((mwp1 == mwp) && (mdotp != mdotp1) || 
  254.                         (mdoto != mdoto1))
  255.                   {
  256.                 if (mshift)
  257.                   kill = TRUE;
  258.                 else
  259.                   copy = TRUE;
  260.                   }
  261.                   } /* end !IsAbort */
  262.               }  /* end didsetmark */
  263.         
  264.         /* if an action triggered, do it now
  265.          */
  266.         if (copy)
  267.           {
  268.         kdelete();
  269.         copyregion(0, 1);
  270.           }
  271.         else if (kill)
  272.           killregion(0, 1);
  273.         
  274.         /* verboseness... remind that something can be pasted
  275.          */
  276.         if (copy || kill)
  277.           ewprintf(pastemsg);
  278.         mshift = FALSE;
  279.         mouseMoving = mouseDown = FALSE;
  280.             didsetmark = FALSE;
  281.       }
  282.       break;
  283.       
  284.     case LEFTDOWN:
  285.     case LEFTDOWNSHIFT:
  286.       mshift = (subcmd == LEFTDOWNSHIFT? TRUE: FALSE);
  287.       getcmdinput(buf);
  288.  
  289.           if (inmacro)
  290.             {
  291.               ewprintf(notinmacro);
  292.               return FALSE;    /* can't record mouse actions */
  293.             }
  294.   
  295.       sscanf(buf, posFormat, &row, &col);
  296.       return(setmousepos(row, col, TRUE));
  297.       
  298.     case DBLCLICK:
  299.           if (inmacro)
  300.             {
  301.               ewprintf(notinmacro);
  302.               return FALSE;    /* can't record mouse actions */
  303.             }
  304.   
  305.           /* mouse-dblclick really should be the end result of
  306.           * of clicking the mouse, then users could map that action
  307.           * just like any keyboard key. But I don't feel like doing
  308.           * that, and in reality NO ui should directly do anything but
  309.           * insert pseudo keystrokes for mapping... in a perfect world.
  310.           */
  311.       if (!inmodeline && (curbp->b_modes[0] == name_mode(DiredStr)))
  312.         return(d_findfile(0, 1));
  313.       else if (!inmodeline && (curbp->b_modes[0] == name_mode(BlistStr)))
  314.         return(seebuffer(0, 1));
  315.       else
  316.             {
  317.               ewprintf("Mouse setting mark...");
  318.           return(setmark(0, 1));
  319.         }
  320.  
  321.     case RIGHTDOWN:
  322.       {
  323.         int s;
  324.         
  325.         getcmdinput(buf);
  326.  
  327.             if (inmacro)
  328.               {
  329.                 ewprintf(notinmacro);
  330.                 return FALSE;    /* can't record mouse actions */
  331.               }
  332.  
  333.         sscanf(buf, posFormat, &row, &col);
  334.         s = setmousepos(row, col, FALSE);
  335.         if (s)
  336.               yank(0, 1);
  337.         return (s);
  338.       }
  339.       
  340.         case M_TIMER:
  341.           {
  342.             int shifted;
  343.  
  344.             if (drawn)
  345.               {
  346.                 movedot(row, col);    /* erase old */
  347.                 drawn = FALSE;
  348.               }
  349.             ewprintf(shiftm);
  350.         getcmdinput(buf);
  351.             sscanf(buf, "%d", &shifted);
  352.             if (shifted)
  353.               ExtendedFunction(function_name(back1page));
  354.             else
  355.               ExtendedFunction(function_name(forw1page));
  356.             break;
  357.           }
  358.  
  359.     case MOVE:
  360.       {
  361.         EWINDOW *save;
  362.         int delta;
  363.         int row_ = row;   /* last move row, col */
  364.         int col_ = col;
  365.         
  366.         getcmdinput(buf);
  367.  
  368.             if (!mouseDown)    /* abort occurred? */
  369.               return (TRUE);    /* leave quietly */
  370.  
  371.             if (inmacro)
  372.               {
  373.                 ewprintf(notinmacro);
  374.                 return FALSE;    /* can't record mouse actions */
  375.               }
  376.         sscanf(buf, posFormat, &row, &col);
  377.         
  378.         /* button down hit mode line? 
  379.          */
  380.         if (inmodeline && !mouseMoving)    /* moving for selection? */
  381.           {
  382.         if (bottommodeline)
  383.           ewprintf(Impossible); 
  384.         else 
  385.           {
  386.                     WindowSizeCursor();
  387.             save = curwp;
  388.             curwp = touchedWp;
  389.             oldrow = touchedWp->w_toprow + touchedWp->w_ntrows - 1;
  390.             delta = abs(row - oldrow);
  391.             if (row < oldrow)
  392.               shrinkwind(0, delta);
  393.             else
  394.               enlargewind(0, delta);
  395.             curwp = save;
  396.             oldrow = row;
  397.           }
  398.           }
  399.  
  400.         /* button down hit source window? 
  401.          */
  402.         else 
  403.           {
  404.         if (!mouseMoving)
  405.           {
  406.                 setmark(0, 1);
  407.             movedot(row, col);
  408.           }
  409.                 else if ((row_ != row) || (col_ != col))
  410.                   {
  411.                     if (drawn)
  412.               movedot(row_, col_);    /* erase old */
  413.             movedot(row, col);        /* draw new */
  414.                   }
  415.  
  416.                 if (!drawn)
  417.           ewprintf(movecopy, mshift ? mv : cp);
  418.                 drawn = TRUE;
  419.                 WindowDragCursor();
  420.         mouseMoving = TRUE;
  421.           }
  422.       }
  423.       
  424.      default:
  425.           break;        /* nothing of interest */
  426.     }
  427.     }
  428.   
  429.   /* gobbledy-goop
  430.    */
  431.   return TRUE;
  432. }
  433.  
  434. /* set dot to row/col, conditionally sets static state
  435.  * variables concerning down position
  436.  */
  437. static BOOL setmousepos(row, col, left)
  438. int row;
  439. int col;
  440. BOOL left;
  441. {
  442.   if (!dottomouse(row, col, TRUE))    /* sets newrow, newcol */
  443.     return (FALSE);
  444.   if (!left)
  445.     return (TRUE);
  446.   
  447.   downrow = oldrow = newrow;        /* save state */
  448.   downcol = oldcol = newcol;
  449.   mouseDown = TRUE;
  450.   mouseMoving = FALSE;
  451.   mwp1 = mwp;                           /* save across move */
  452.   mdotp1 = mdotp;
  453.   mdoto1 = mdoto;
  454.   mcol1 = getcolpos() - 1;              /* evaluated location */
  455.   
  456.   /* get globals to the right place...draw a marker
  457.    */
  458.   WindowArrowCursor();        /* kinda limbo cursor.. */
  459.   ewprintf("Cntrl-left is scroll; drag for region select.");
  460.   if (!inmodeline)
  461.     if (g_hasFocus)
  462.       {
  463.         update();
  464.         didsetmark = TRUE;
  465.       }
  466.   return (TRUE);
  467. }
  468. /* visible region-selection drawing...
  469.  */
  470. static void movedot(row, col)
  471. int row, col;
  472. {
  473.   dottomouse(row, col, TRUE);
  474.   update();
  475.   DrawMarker();
  476.   ttflush(FALSE);
  477. }
  478. /* parse a subcommand string to a integer verb
  479.  */
  480. static int subcommand(s)
  481. char *s;
  482. {
  483.   /* this just moves the strcmp's out of direct sight! 
  484.    */
  485.   if (strcmp(s, LeftUp) == 0)
  486.     return(LEFTUP);
  487.   else if (strcmp(s, RightDwn) == 0)
  488.     return(RIGHTDOWN);
  489.   else if (strcmp(s, LeftDwn) == 0)
  490.     return(LEFTDOWN);
  491.   else if (strcmp(s, LeftDwnShift) == 0)
  492.     return(LEFTDOWNSHIFT);
  493.   else if (strcmp(s, DoubleClick) == 0)
  494.     return(DBLCLICK);
  495.   else if (strcmp(s, MoveStr) == 0)
  496.     return(MOVE);
  497.   else if (strcmp(s, MouseAbort) == 0)
  498.     return(M_ABORT);
  499.   else if (strcmp(s, MouseTimer) == 0)
  500.     return(M_TIMER);
  501.   
  502.   /* unknown */
  503.   else
  504.     return (-1);
  505. }
  506. #endif /* WHOLE FILE */
  507.  
  508.